using System;
using System.Collections.Generic;

using NHibernate;
using NHibernate.Criterion;

using Blog.Net.Common.DataObjects;
using Blog.Net.Business.BusinessObjects;
using Blog.Net.Business.DataTransferObjects;

namespace Blog.Net.DataAccess.DataControls
{
    /// <summary>
    /// Data Control object for BlogEntry.
    /// </summary>
    public partial class BlogEntryDataControl
    {

        /// <summary>
        /// Gets the latest blog entries.
        /// </summary>
        /// <returns></returns>
        public IList<BlogEntryBO> GetLatest()
        {
            return GetLatest(1, -1, null);
        }

        /// <summary>
        /// Gets the latest blog entries.
        /// </summary>
        /// <param name="RecordCount">The record count.</param>
        /// <returns></returns>
        public IList<BlogEntryBO> GetLatest(int RecordCount)
        {
            return GetLatest(RecordCount, -1, null);
        }

        /// <summary>
        /// Gets the latest blog entries.
        /// </summary>
        /// <param name="RecordCount">The record count.</param>
        /// <param name="EntryId">The entry id.</param>
        /// <param name="Month">The month.</param>
        /// <returns></returns>
        public IList<BlogEntryBO> GetLatest(int RecordCount, int EntryId, string MonthYear)
        {
            ICriteria criteria = dataControl.GetCriteria();
            if (EntryId != -1)
                criteria.Add(Expression.Eq(FieldNames.Id, EntryId));
            else
                criteria.AddOrder(Order.Desc(FieldNames.CreateDate));

            if (!string.IsNullOrEmpty(MonthYear))
            {
                DateTime start = new DateTime(int.Parse(MonthYear.Split('.')[1]) + 2000, int.Parse(MonthYear.Split('.')[0]), 1);
                DateTime end = new DateTime(int.Parse(MonthYear.Split('.')[1]) + 2000, int.Parse(MonthYear.Split('.')[0]), 1).AddMonths(1).AddDays(-1);
                criteria.Add(Expression.Ge(FieldNames.CreateDate, start));
                criteria.Add(Expression.Le(FieldNames.CreateDate, end));
            }

            if (RecordCount != -1)
                criteria.SetMaxResults(RecordCount);

            IList<BlogEntry> retVal = dataControl.GetQueryResult(criteria);

            if (retVal != null)
                return ConvertPOCOListToBOList(retVal);

            return new List<BlogEntryBO>();
        }

        /// <summary>
        /// Gets the month counts.
        /// </summary>
        /// <param name="RecordCount">The record count.</param>
        /// <returns></returns>
        public IList<EntryStatsDTO> GetMonthCounts(int RecordCount)
        {
            IList<EntryStatsDTO> statsList = new List<EntryStatsDTO>();

            ICriteria criteria = dataControl.GetCriteria();
            criteria.AddOrder(Order.Desc(FieldNames.CreateDate));

            IList<BlogEntry> retVal = dataControl.GetQueryResult(criteria);

            foreach (BlogEntry blog in retVal)
            {
                bool exists = false;
                foreach (EntryStatsDTO stat in statsList)
                {
                    if (stat.CreateMonth == new DateTime(blog.CreateDate.Year, blog.CreateDate.Month, 1))
                    {
                        stat.EntryCount++;
                        exists = true;
                    }
                }
                if (!exists)
                    statsList.Add(new EntryStatsDTO(new DateTime(blog.CreateDate.Year, blog.CreateDate.Month, 1), 1));

                if (statsList.Count > RecordCount)
                {
                    statsList.RemoveAt(RecordCount);
                    break;
                }
            }

            return statsList;
        }

        public bool UpdateStats(int? Id, int Points, int Votes)
        {
            BlogEntryBO entry = GetById(Id);
            entry.Points = Points;
            entry.Votes = Votes;
            if (Save(entry) > 0)
                return true;

            return false;
        }
    }
}

